Skip to content

fix: resolve all critical parser and macro issues#70

Merged
dannywillems merged 4 commits intomasterfrom
fix/critical-issues
Feb 8, 2026
Merged

fix: resolve all critical parser and macro issues#70
dannywillems merged 4 commits intomasterfrom
fix/critical-issues

Conversation

@dannywillems
Copy link
Contributor

Summary

  • Parser: rewrite tree builder fragment mode and pop_until — Replace
    broken parent_idx * 1000 + child_idx index arithmetic with proper
    tree navigation using document.root as virtual container. Previously
    silently broke with >1000 children or >2 nesting levels. Implement
    proper pop_until that walks the stack backwards instead of the stub
    that only popped one element. Remove unwrap() calls that could panic
    on malformed input. Also eliminates the open_elements.clone() on
    every node insertion by extracting navigate_to_element as a free
    function.

  • Macro: emit compile error for multi-child for-loops — Previously
    for item in #items { li { #item } hr } silently dropped the hr.
    Now emits: "for loop body must contain exactly one element".

  • Macro: remove Rb/Rtc from to_pascal_case — These mapped to types
    that don't exist in ironhtml-elements, causing confusing errors.

Test plan

  • 8 new tree builder tests (deep nesting, 1100 children, void
    elements in fragments, unmatched end tags, pop_until, multiple
    top-level fragments)
  • All 171 existing tests pass
  • Clippy clean (pedantic + nursery)

Closes #47, closes #48, closes #49, closes #50, closes #51

- Replace broken fragment_nodes/index arithmetic (parent_idx * 1000 +
  child_idx) with document.root as virtual container, reusing the same
  navigation as non-fragment mode. Previously silently broke with >1000
  children or >2 nesting levels.

- Implement proper pop_until that walks open_element_names backwards
  to find matching tag, instead of the stub that only popped once.

- Remove unwrap() calls on open_elements.last() that could panic on
  malformed input; the refactored code no longer needs them.

- Extract navigate_to_element as free function taking &mut Element
  and &[usize], eliminating the open_elements.clone() on every
  node insertion.

Closes #47, closes #48, closes #49
Previously, for-loop bodies in html! macro silently dropped all
children except the first element. Now emits a clear compile error:
"for loop body must contain exactly one element".

Closes #50
These mapped to types that don't exist in ironhtml-elements, causing
confusing compiler errors when used in html! macro. The entries were
also identity mappings (no-ops), since to_pascal_case already produces
the correct output.

Closes #51
28 new tests covering:
- pop_until: skips intermediates, no-match preserves root, closes
  correct level with nested same-tag elements
- Fragment nesting: 5 levels deep, text at every level, siblings
  with children
- Fragment void elements: multiple voids, voids between text, voids
  with attributes, voids nested inside tables
- Fragment comments: top-level, inside elements, between siblings
- Fragment top-level: text-only, mixed text+elements, empty, whitespace
- Malformed input: only end tags, extra end tags, unclosed tags,
  interleaved tags, deeply mismatched nesting
- Full document: head elements, implicit body, implicit head+body,
  title extraction, round-trip parse
@dannywillems dannywillems merged commit 61a00a3 into master Feb 8, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant